/**
 * 基于STS临时凭证的阿里云OSS直传模块
 * 小程序直接上传到阿里云OSS
 */

import http from './http.js'

// OSS配置
const OSS_CONFIG = {
    bucket: 'iepsy',
    region: 'oss-cn-beijing',
    domain: 'iepsy.oss-cn-beijing.aliyuncs.com'
}

// STS凭证缓存
let stsCredentials = null
let credentialsExpireTime = 0

/**
 * 获取STS临时凭证
 * @returns {Promise<Object>} STS凭证信息
 */
async function getSTSCredentials() {
    try {
        // 检查缓存的凭证是否还有效（提前5分钟刷新）
        const now = Date.now()
        if (stsCredentials && credentialsExpireTime > now + 5 * 60 * 1000) {
            return stsCredentials
        }
        
        console.log('获取STS临时凭证...')
        
        // 调用后端接口获取STS凭证
        const result = await http.get('/oss/sts')
        
        if (result && result.Credentials) {
            stsCredentials = result.Credentials
            // 解析过期时间
            credentialsExpireTime = new Date(result.Credentials.Expiration).getTime()
            
            console.log('STS凭证获取成功，过期时间:', result.Credentials.Expiration)
            return stsCredentials
        } else {
            throw new Error('STS凭证格式错误')
        }
    } catch (error) {
        console.error('获取STS凭证失败:', error)
        throw new Error(`获取STS凭证失败: ${error.message}`)
    }
}

/**
 * 生成文件上传路径
 * @param {string} fileName - 原始文件名
 * @param {string} type - 文件类型标识
 * @param {string} category - 分类（agency或apply）
 * @returns {string} 生成的文件路径
 */
function generateFilePath(fileName, type, category = 'agency') {
    const now = new Date()
    const year = now.getFullYear()
    const month = String(now.getMonth() + 1).padStart(2, '0')
    const day = String(now.getDate()).padStart(2, '0')
    const timestamp = Date.now()
    
    // 提取文件扩展名
    const ext = fileName.split('.').pop() || 'jpg'
    
    // 生成新的文件名
    const newFileName = `${timestamp}.${ext}`
    
    // 根据分类生成路径
    let basePath = ''
    if (category === 'agency') {
        basePath = `upload/sa/agenc/${year}/${month}/${day}/${newFileName}`
    } else if (category === 'apply') {
        basePath = `upload/sa/apply/${year}/${month}/${day}/${newFileName}`
    } else {
        // 默认路径
        basePath = `upload/sa/agenc/${year}/${month}/${day}/${newFileName}`
    }
    
    return basePath
}

/**
 * 从URL中提取OSS key
 * @param {string} url - 文件URL或key路径
 * @returns {string} OSS key路径
 */
function extractKeyFromUrl(url) {
    if (!url) return ''
    
    // 如果已经是key路径（不包含http），直接返回
    if (!url.startsWith('http')) {
        return url
    }
    
    // 移除域名部分，获取key
    const domain = `https://${OSS_CONFIG.domain}/`
    if (url.startsWith(domain)) {
        return url.replace(domain, '')
    }
    
    // 尝试从其他格式的URL中提取key
    try {
        const urlObj = new URL(url)
        return urlObj.pathname.substring(1) // 移除开头的 /
    } catch (error) {
        console.error('无法解析URL:', url, error)
        return ''
    }
}

// 移除了getOSSUploadSignature函数，直接使用STS凭证

/**
 * 生成OSS POST上传的policy和signature
 * @param {string} ossKey - OSS文件路径
 * @param {Object} credentials - STS凭证
 * @returns {Object} policy和signature信息
 */
async function generateOSSPolicy(ossKey, credentials) {
    const result = await http.get('/oss/policy',{file: ossKey,secret: credentials.AccessKeySecret})
    console.log('获取OSS上传策略成功：', result)
    return {
        policy: result.policy || result.data?.policy,
        signature: result.signature || result.data?.signature
    }
}

/**
 * 使用STS凭证上传文件到OSS
 * @param {string} filePath - 本地文件路径
 * @param {string} ossKey - OSS文件路径
 * @param {Object} credentials - STS凭证
 * @returns {Promise<Object>} 上传结果
 */
function uploadWithSTS(filePath, ossKey, credentials) {
    return new Promise(async (resolve, reject) => {
        console.log('使用STS凭证上传到OSS...')
        
        // 生成policy和signature
        const { policy, signature } = await generateOSSPolicy(ossKey, credentials)
        
        // 构建表单数据
        const formData = {
            key: ossKey,
            policy: policy || '',
            OSSAccessKeyId: credentials.AccessKeyId,
            signature: signature || '',
            'x-oss-security-token': credentials.SecurityToken,
            'x-oss-object-acl': 'public-read',
            'success_action_status': '200'
        }
        
        console.log('STS上传配置:', { 
            ossKey, 
            formData: {
                ...formData,
                policy: policy ? policy.substring(0, 50) + '...' : 'undefined',
                signature: signature ? signature.substring(0, 20) + '...' : 'undefined'
            }
        })
        
        // 执行上传
        uni.uploadFile({
            url: `https://${OSS_CONFIG.domain}`,
            filePath: filePath,
            name: 'file',
            formData: formData,
            success: (res) => {
                console.log('STS上传响应:', res)
                
                if (res.statusCode === 200 || res.statusCode === 204) {
                    resolve({
                        url: ossKey, // 返回key路径，不含域名前缀
                        key: ossKey,
                        type: 'image',
                        originalName: filePath.split('/').pop()
                    })
                } else {
                    console.error('STS上传失败，状态码:', res.statusCode, '响应:', res.data)
                    reject(new Error(`STS上传失败，状态码: ${res.statusCode}`))
                }
            },
            fail: (error) => {
                console.error('STS上传请求失败:', error)
                reject(new Error(`STS上传请求失败: ${error.errMsg || '网络错误'}`))
            }
        })
    })
}

/**
 * 直接上传文件到OSS
 * @param {string} filePath - 本地文件路径
 * @param {string} type - 文件类型标识
 * @param {string} category - 分类（agency或apply）
 * @returns {Promise<Object>} 上传结果
 */
export const uploadToOSS = async (filePath, type, category = 'agency') => {
    try {
        // 从文件路径提取文件名
        const fileName = filePath.split('/').pop() || `${type}_${Date.now()}.jpg`
        
        console.log('开始OSS直传:', { filePath, fileName, type, category })
        
        // 1. 获取STS临时凭证
        const credentials = await getSTSCredentials()
        
        // 2. 生成文件路径
        const ossKey = generateFilePath(fileName, type, category)
        
        // 3. 直接使用STS凭证上传
        console.log('使用STS凭证直接上传...')
        return await uploadWithSTS(filePath, ossKey, credentials)
        
    } catch (error) {
        console.error('OSS上传异常:', error)
        throw new Error(`上传失败: ${error.message}`)
    }
}

/**
 * 删除OSS文件
 * @param {string} fileUrl - 文件URL或key路径
 * @returns {Promise<Object>} 删除结果
 */
export const deleteOSSFile = async (fileUrl) => {
    try {
        if (!fileUrl) {
            throw new Error('文件URL不能为空')
        }
        
        console.log('开始删除OSS文件:', fileUrl)
        
        // 1. 获取STS临时凭证
        const credentials = await getSTSCredentials()
        
        // 2. 提取OSS key
        const ossKey = extractKeyFromUrl(fileUrl)
        if (!ossKey) {
            throw new Error('无法从URL中提取文件路径')
        }
        
        console.log('删除配置:', { ossKey })
        
        // 3. 执行删除请求
        return new Promise((resolve, reject) => {
            uni.request({
                url: `https://${OSS_CONFIG.domain}/${ossKey}`,
                method: 'DELETE',
                header: {
                    'Authorization': `OSS ${credentials.AccessKeyId}:${credentials.AccessKeySecret}`,
                    'x-oss-security-token': credentials.SecurityToken,
                    'Date': new Date().toUTCString()
                },
                success: (res) => {
                    console.log('OSS删除响应:', res)
                    
                    if (res.statusCode === 204 || res.statusCode === 200) {
                        resolve({
                            key: ossKey,
                            originalUrl: fileUrl
                        })
                    } else {
                        console.error('OSS删除失败，状态码:', res.statusCode, '响应:', res.data)
                        reject(new Error(`删除失败，状态码: ${res.statusCode}`))
                    }
                },
                fail: (error) => {
                    console.error('OSS删除请求失败:', error)
                    reject(new Error(`删除请求失败: ${error.errMsg || '网络错误'}`))
                }
            })
        })
        
    } catch (error) {
        console.error('删除OSS文件异常:', error)
        throw new Error(`删除失败: ${error.message}`)
    }
}

/**
 * 清除STS凭证缓存（用于强制刷新）
 */
export const clearSTSCache = () => {
    stsCredentials = null
    credentialsExpireTime = 0
    console.log('STS凭证缓存已清除')
}

export default {
    uploadToOSS,
    deleteOSSFile,
    clearSTSCache
}